package app

// Confluence 单元流域汇流，包括坡地汇流和河网汇流，都采用线性水库法
type Confluence struct {
	//========模型参数========//
	CS float64 `json:"CS"` //地面径流消退系数，敏感
	CI float64 `json:"CI"` //壤中流消退系数，敏感
	CG float64 `json:"CG"` //地下水消退系数，敏感
	CR float64 `json:"CR"` //河网蓄水消退系数，敏感
	IM float64 `json:"IM"` //不透水面积占全流域面积的比例，不敏感

	//========模型状态========//
	QS float64 `json:"QS"`
	//double QS;   //单元流域地面径流，m3/s
	QI float64 `json:"QI"`
	//double QI;   //单元流域壤中流，m3/s
	QG float64 `json:"QG"`
	//double QG;   //单元流域地下径流，m3/s
	QT float64 `json:"QT"`
	//double QT;   //单元流域河网总入流
	//（进入单元面积的地面径流、壤中流和地下径流之和），m3/s

	QU float64 `json:"QU"`
	//double QU;   //单元流域出口流量，m3/s

	RS float64 `json:"RS"`
	//double RS;   //地面径流量，mm
	RI float64 `json:"RI"`
	//double RI;   //壤中流径流量，mm
	RG float64 `json:"RG"`
	//double RG;   //地下径流量，mm
	RIM float64 `json:"RIM"`
	//double RIM;   //不透水面积上的产流量，mm
	QI0 float64 `json:"QI0"`
	//double QI0;  //QI(t-1)，前一时刻壤中流，m3/s
	QG0 float64 `json:"QG0"`
	//double QG0;  //QG(t-1)，前一时刻地下径流，m3/s
	QU0 float64 `json:"QU0"`
	//double QU0;  //QU(t-1)，前一时刻单元流域出口流量，m3/s
	F float64 `json:"F"`
	//double F;   //单元流域面积，km2
	U float64 `json:"U"`
	//double U;   //单位转换系数
	M float64 `json:"M"`
	//double M;   //一天划分的计算时段数
	CSD float64 `json:"CSD"`
	//double CSD;   //计算时段内地面径流蓄水库的消退系数
	CID float64 `json:"CID"`
	//double CID;   //计算时段内壤中流蓄水库的消退系数
	CGD float64 `json:"CGD"`
	//double CGD;   //计算时段内地下水蓄水库的消退系数
	CRD float64 `json:"CRD"`
	//double CRD;   //计算时段内河网蓄水消退系数
	DT int `json:"DT"`
	//double dt;   //模型计算时段长,h

}

func (e *Confluence) SetParams(para *Params) {
	// 默认参数
	e.DT = 24

	e.CI = para.MCI
	e.CS = para.MCS
	e.CG = para.MCG
	e.CR = para.MCR
	e.IM = para.MIM
}

func (e *Confluence) SetState(a *State) {
	e.RIM = a.RIM
	e.RS = a.RS
	e.RI = a.RI
	e.RG = a.RG
	e.QS = a.QS
	e.QI = a.QI
	e.QG = a.QG
	e.QU0 = a.QU
	e.F = a.F
	e.DT = int(a.DT)
}

func (e *Confluence) Calculate() {
	e.RS = e.RS * (1 - e.IM)
	e.RI = e.RI * (1 - e.IM)
	e.RG = e.RG * (1 - e.IM)

	e.M = float64(24.0 / e.DT) //一天划分的计算时段数

	//坡地汇流
	e.U = e.F / 3.6 / float64(e.DT) //单位转换系数

	e.QS = e.CS*e.QS + (1-e.CS)*(e.RS+e.RIM)*e.U //地面径流流入地面径流水库，
	//经过消退(CSD)，成为地面径流对河网的总入流QS

	e.QI = e.CI*e.QI + (1-e.CI)*e.RI*e.U //壤中流流入壤中流水库，
	//经过消退(CID)，成为壤中流对河网的总入流QI

	e.QG = e.CG*e.QG + (1-e.CG)*e.RG*e.U //地下径流进入地下水蓄水库，经过地下水
	//蓄水库的消退(CGD)，成为地下水对河网的总入流QG

	e.QT = e.QS + e.QI + e.QG

	//河网汇流，采用线性水库法，且仅当单元流域面积大于200km2时才计算河网汇流
	if e.F < 200 {
		e.QU = e.QT //单元流域面积不大且河道较短，对水流运动的调蓄作用通常较小
		//将这种调蓄作用合并在地面径流和地下径流中一起考虑所带来的误差通常可以忽略
	} else {
		e.QU = e.CR*e.QU + (1-e.CR)*e.QT //线性水库法
		//只有在单元流域面积较大或流域坡面汇流极其复杂时
		//才考虑单元面积内的河网汇流
	}
}

func (e *Confluence) UpdateState(s *State) {
	s.QS = e.QS
	s.QI = e.QI
	s.QG = e.QG
	s.QU = e.QU
	s.QU0 = e.QU0
}
